<link rel="import" href="app-form.html">
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">

<dom-module id="sub-form">
    <template>
        <style include="shared-styles forms">
             :host app-form {
                margin-left: 24px;
                margin-top: -80px !important;
                margin-bottom: 32px;
            }

            :host([moderate-top]) app-form {
                margin-top: -50px !important;
            }

            .title {
                margin-top: 16px;
                margin-bottom: 8px;
            }

            paper-icon-button {
                margin-left: -12px;
            }

            paper-icon-button.remove {
                margin-top: -40px;
                float: right;
            }
        </style>
        <template is="dom-repeat" items="{{items}}">
            <div class="title">
                <strong>[[indexPlusOne(index)]].</strong>
            </div>
            <paper-icon-button class="remove" icon="delete" on-tap="deleteItem" hidden$="[[_computeShowDelete(index)]]">-</paper-icon-button>
            <app-form id$="sub-form-[[index]]" fields="{{item}}" display-buttons="[[_calcDisplayButtons()]]" horizontal-layout="[[horizontal]]" form-ready={{formReady}}></app-form>
            <br/>
        </template>
        <paper-icon-button class="add" icon="add" on-tap="addItem" hidden$="[[hideAddButton(min,max,items.length)]]">+</paper-icon-button>
    </template>
    <script>
        Polymer({
            is: 'sub-form',
            /**
             * Fired when a response is received.
             *
             * @event response
             */
            /**
             * Fired when a request is made.
             *
             * @event request
             */
            /**
             * Fired when the leadValue is changed.
             *
             * @event leadchange
             */
            properties: {
                id: {
                    type: String
                },
                options: {
                    type: Array,
                    value: function () {
                        return []
                    }
                },
                itemName: {
                    type: String
                },
                items: {
                    type: Array,
                    value: function () {
                        return []
                    },
                    notify: true
                },
                fieldName: {
                    type: String
                },
                min: {
                    type: Number,
                    value: 1
                },
                max: {
                    type: Number
                },
                activeItem: {
                    type: String
                },
                formReady: {
                    type: Boolean,
                    value: false,
                    notify: true
                },
                show: {
                    type: Boolean
                },
                horizontal: {
                    type: Boolean,
                    value: false
                },
                moderateTop: {
                    type: Boolean,
                    value: true,
                    reflectToAttribute: true
                },
            },
            observers: [
                '_optionsChanged(options.*)',
                '_itemsChanged(items.splices, items.*)',
                '_minChanged(min)',
                '_showChanged(show)'
            ],
            listeners: {
                'keyup': '_itemsChanged',
                'tap': '_setActiveItem'
            },
            hideAddButton: function(min, max, itemslength) {
                return min == max == itemslength;
            },
            _minChanged: function (min) {
                for (var i = 1; i <= this.min; i++) {
                    this.addItem();
                }
            },
            _setActiveItem: function (e) {
                //set changing item
                var parent = e.path.find(function(p){
                    return p.tagName == 'APP-FORM';
                });
                if (parent && parent.id)
                    this.set('activeItem', parent.id.split('sub-form-')[1]);
                else
                    this.set('activeItem', null);
            },
            _itemsChanged: function () {
                this.dispatchEvent(new CustomEvent('fields-changed',{ bubbles: true, composed: true, file: 'sub-form.html : _itemsChanged()'}));
            },
            _optionsChanged: function (options) {
                var index = options.path.split('.')[1];
                if (this.activeItem && index) {
                    // update specific item value
                    if (options.path.endsWith('value')){
                        this.set('items.'+this.activeItem+'.'+index.replace('#','')+'.value', options.value);
                    }
                    // update all items options
                    else if (options.path.endsWith('options')) {
                        for (var i=0; i<this.items.length; i++){
                            this.set('items.'+i+'.'+index.replace('#','')+'.options', options.value);
                        }
                    }
                }
            },
            _calcDisplayButtons: function () {
                return false;
            },
            _showChanged: function(show) {
                if (!show) {
                    this.clear();
                }
            },
            clear:  function() {
                this.set('items', []);
            },
            addItem: function () {
                function copy(o) { // deep copy an array of objects
                    var output, v, key;
                    output = Array.isArray(o) ? [] : {};
                    if (o) {
                        for (key in o) {
                            v = o[key];
                            output[key] = (typeof v === "object") ? copy(v) : v;
                        }
                    }
                    return output;
                }

                if (this.options) {
                    if (!this.max || this.items.length < this.max) {
                        var opts = copy(this.options); // deep copy options
                        opts.forEach(function (o) {
                            o.value = o.defaultValue;
                        })
                        this.push('items', opts);
                    } else {
                        this.dispatchEvent(new CustomEvent('toast', { bubbles: true, composed: true, detail: {
                            msg: 'Only up to ' + this.max + ' ' + this.itemName + 's are allowed.',
                            duration: 3000
                        } }));

                        this.shadowRoot.querySelector('.add').setAttribute('disabled', true);
                    }
                    this.dispatchEvent(new CustomEvent('fields-changed', { bubbles: true, composed: true, file: 'sub-form.html : addItem()'}));
                }
            },
            deleteItem: function (e) {
                // console.log('deleteItem', e.model.__data__.index);
                if (!this.min || this.items.length > this.min) {
                    this.splice('items', e.model.__data.index, 1);
                    this.shadowRoot.querySelector('.add').removeAttribute('disabled');
                    this.async(function () {
                        this.dispatchEvent(new CustomEvent('fields-changed', { bubbles: true, composed: true, file: 'sub-form.html : deleteItem()'}));
                    }.bind(this), 200)
                } else {
                    this.dispatchEvent(new CustomEvent('toast', { bubbles: true, composed: true, detail:  {
                        msg: 'Minimun ' + this.max + ' ' + this.itemName + 's are required.',
                        duration: 3000
                    } }));
                }
            },
            indexPlusOne: function (i) {
                return i + 1;
            },
            _computeShowDelete: function (index) {
                return this.min ? index < this.min : true;
            }
        });
    </script>
</dom-module>